Entre para se conectar em tempo real
Não tem conta? Cadastre-se
Crie sua conta em poucos segundos
account_circle

Adicionar Foto de Perfil

Já tem conta? Faça Login

Conversas

logout

Adicionar Amigos

Meu Perfil

face

Alterar Foto

Foto

arrow_back Avatar
Carregando... offline
more_vert
cloud_upload

Solte o arquivo para enviar

attach_file send
chat Conversas
person_add Adicionar
account_circle Perfil
if(res.sucesso) { exibirToast("Solicitação respondida."); fecharJanelaChat(); } else { exibirToast(res.erro); } }); } function gerenciarBloqueioAmigo() { let novo = amigoObjetoAtual.euBloqueei ? 'ACEITO' : 'BLOQUEADO'; let fd = new FormData(); fd.append('acao', 'alterarStatusBloqueio'); fd.append('meuEmail', usuarioLogado.email); fd.append('emailAmigo', amigoAtivoEmail); fd.append('novoStatus', novo); fetch('index.php', { method: 'POST', body: fd }) .then(r => r.json()) .then(res => { if(res.sucesso) { exibirToast(novo === 'BLOQUEADO' ? "Usuário bloqueado!" : "Usuário desbloqueado!"); fecharJanelaChat(); } else { exibirToast(res.erro); } }); } function atualizarBadgeTotal() { if(!usuarioLogado) return; let fd = new FormData(); fd.append('acao', 'buscarNaoLidasTotal'); fd.append('meuEmail', usuarioLogado.email); fetch('index.php', { method: 'POST', body: fd }) .then(r => r.json()) .then(res => { const el = document.getElementById('badge-total-mensagens'); if(res.total && res.total > 0) { el.innerText = res.total; el.style.display = 'block'; } else { el.style.display = 'none'; } }); } // Inicialização da Página document.addEventListener("DOMContentLoaded", function() { if (obterSession()) { entrarNoApp(); } else { deslogar(); } setInterval(atualizarBadgeTotal, 4000); }); MinhaAutoria ? 'flex' : 'none'; menu.style.top = `${e.clientY}px`; menu.style.left = `${e.clientX}px`; menu.style.display = 'block'; } async function solicitarExclusaoMensagem() { if (!mensagemSelecionadaIdContexto) return; const res = await fazerRequisicaoAPI({ acao: 'excluirMensagem', mensagemId: mensagemSelecionadaIdContexto }); if (res.sucesso) { exibirNotificacaoToast("Mensagem revogada.", "success"); sincronizarFeedMensagensAtivo(); } } async function solicitarEdicaoMensagem() { if (!mensagemSelecionadaIdContexto) return; const novoTexto = prompt("Insira a nova retificação da mensagem:"); if (!novoTexto) return; const res = await fazerRequisicaoAPI({ acao: 'editarMensagem', mensagemId: mensagemSelecionadaIdContexto, novoTexto: novoTexto }); if (res.sucesso) { exibirNotificacaoToast("Mensagem retificada.", "success"); sincronizarFeedMensagensAtivo(); } else { exibirNotificacaoToast(res.erro || "Falha ao editar.", "error"); } } // COESÃO UX: DRAG AND DROP DIRECTLY INTO CHAT CANVAS function configurarMecanismoArrastarArquivos() { const area = document.getElementById('chat-screen'); const overlay = document.getElementById('drag-overlay'); window.addEventListener('dragover', (e) => e.preventDefault()); window.addEventListener('drop', (e) => e.preventDefault()); area.addEventListener('dragenter', (e) => { e.preventDefault(); overlay.style.display = 'flex'; }); overlay.addEventListener('dragleave', (e) => { e.preventDefault(); overlay.style.display = 'none'; }); area.addEventListener('drop', async (e) => { e.preventDefault(); overlay.style.display = 'none'; if (!emailChatAberto) return; const files = e.dataTransfer.files; if (files.length > 0) { document.getElementById('chat-file-input').files = files; exibirNotificacaoToast(`Arquivo detectado via Drop: ${files[0].name}. Enviando...`, 'info'); await enviarMensagemWorkspace(); } }); } ns', amigoEmail: emailChatAberto }); if (res.erro) return; const feed = document.getElementById('feed-mensagens'); const scrollNoFim = (feed.scrollHeight - feed.scrollTop <= feed.clientHeight + 160); feed.innerHTML = ''; res.forEach(m => { const ladoBubble = m.isRemetente ? 'sent' : 'received'; const checkIcon = m.isRemetente ? (m.visualizada === 1 ? `done_all` : `done`) : ''; let corpoMarkup = `
${m.mensagem}
`; if (m.tipo === 'imagem') { corpoMarkup = `
`; } else if (m.tipo === 'video') { corpoMarkup = `
`; } feed.innerHTML += `
${corpoMarkup}
${m.data} ${checkIcon}
`; }); if (scrollNoFim) feed.scrollTop = feed.scrollHeight; } async function enviarMensagemFormulario() { const txtField = document.getElementById('chat-input-msg'); const mensagemTexto = txtField.value.trim(); const arqInput = document.getElementById('chat-file-input'); if (mensagemTexto === "" && arqInput.files.length === 0) return; const form = new FormData(); form.append('acao', 'enviarMensagem'); form.append('emailRemetente', sessaoAtiva.email); form.append('emailDestinatario', emailChatAberto); form.append('mensagem', mensagemTexto); if (arqInput.files.length > 0) { form.append('arquivo', arqInput.files[0]); } txtField.value = ''; arqInput.value = ''; document.getElementById('dropdown-emojis-menu').style.display = 'none'; const res = await chamarServidorAPI(form, true); if (res.erro) { dispararToastBanner(res.erro, 'error'); } else { sincronizarFeedMensagensWorkspace(); renderizarListaConversas(true); } } function alternarVisibilidadePainelEmojis(e) { e.stopPropagation(); const menu = document.getElementById('dropdown-emojis-menu'); menu.style.display = menu.style.display === 'grid' ? 'none' : 'grid'; } function inserirEmojiPainel(emoji) { const field = document.getElementById('chat-input-msg'); field.value += emoji; field.focus(); } function notificarFicheiroCarregado(input) { if (input.files.length > 0) { dispararToastBanner(`Mídia anexada: ${input.files[0].name}. Pressione Enviar.`, 'success'); } } function enviarReacaoCurtida(emoji) { const input = document.getElementById('chat-input-msg'); input.value = emoji; enviarMensagemFormulario(); } function sinalizarDigitandoAviso() { const agora = Date.now(); if (agora - tempoUltimoSinalDigitando > 3000) { tempoUltimoSinalDigitando = agora; chamarServidorAPI({ acao: 'registrarStatusDigitando', emailRemetente: sessaoAtiva.email, emailAmigo: emailChatAberto }); } } async function processarAjustesPerfil(e) { e.preventDefault(); const form = new FormData(); form.append('acao', 'salvarPerfil'); form.append('id', document.getElementById('edit-id').value); form.append('nome', document.getElementById('edit-nome').value); form.append('idade', document.getElementById('edit-idade').value); form.append('bio', document.getElementById('edit-bio').value); form.append('senha', document.getElementById('edit-senha').value); if (cacheFotoBase64) form.append('foto', cacheFotoBase64); const res = await chamarServidorAPI(form, true); if (res.sucesso) { dispararToastBanner("Perfil salvo com sucesso!", "success"); sessaoAtiva.nome = document.getElementById('edit-nome').value; sessaoAtiva.idade = document.getElementById('edit-idade').value; sessaoAtiva.bio = document.getElementById('edit-bio').value; if (res.fotoAtualizada) sessaoAtiva.foto = res.fotoAtualizada; localStorage.setItem('ggmsg_v4_session', JSON.stringify(sessaoAtiva)); montarAmbienteUsuarioAutenticado(); } else { dispararToastBanner(res.erro || "Falha ao gravar os dados.", "error"); } } async function alternarBloqueioOperacional() { if (!dadosAmigoChatAberto) return; const novo = dadosAmigoChatAberto.euBloqueei ? 'ACEITO' : 'BLOQUEADO'; const res = await chamarServidorAPI({ acao: 'alterarStatusBloqueio', emailAmigo: emailChatAberto, novoStatus: novo }); if (!res.erro) { dispararToastBanner(`Definição de privacidade atualizada para ${novo}.`, 'success'); renderizarListaConversas(true); } } async function limparHistoricoMensagens() { if (!confirm("Tem certeza que deseja limpar as mensagens dessa conversa para você?")) return; const res = await chamarServidorAPI({ acao: 'excluirConversa', amigoEmail: emailChatAberto }); if (res.sucesso) { dispararToastBanner("Histórico expurgado.", "success"); sincronizarFeedMensagensWorkspace(); } } function gerirContextMenuBubble(e, msgId, isMeu) { e.preventDefault(); mensagemSelecionadaContextoId = msgId; const menu = document.getElementById('msg-context-menu'); document.getElementById('ctx-edit-option').style.display = isMeu ? 'flex' : 'none'; menu.style.top = `${e.clientY}px`; menu.style.left = `${e.clientX}px`; menu.style.display = 'block'; } async function dispararExclusaoMensagemPopup() { if (!mensagemSelecionadaContextoId) return; const res = await chamarServidorAPI({ acao: 'excluirMensagem', mensagemId: mensagemSelecionadaContextoId }); if (res.sucesso) { dispararToastBanner("Mensagem revogada com sucesso.", "success"); sincronizarFeedMensagensWorkspace(); } } async function dispararEdicaoMensagemPopup() { if (!mensagemSelecionadaContextoId) return; const texto = prompt("Modifique o conteúdo da sua mensagem:"); if (!texto) return; const res = await chamarServidorAPI({ acao: 'editarMensagem', mensagemId: mensagemSelecionadaContextoId, novoTexto: texto }); if (res.sucesso) { dispararToastBanner("Mensagem retificada.", "success"); sincronizarFeedMensagensWorkspace(); } else { dispararToastBanner(res.erro, "error"); } } function inicializarMecanismoDragDrop() { const alvo = document.getElementById('chat-screen'); const overlay = document.getElementById('drag-overlay'); window.addEventListener('dragover', e => e.preventDefault()); window.addEventListener('drop', e => e.preventDefault()); alvo.addEventListener('dragenter', e => { e.preventDefault(); overlay.style.display = 'flex'; }); overlay.addEventListener('dragleave', e => { e.preventDefault(); overlay.style.display = 'none'; }); alvo.addEventListener('drop', async e => { e.preventDefault(); overlay.style.display = 'none'; if (!emailChatAberto) return; const ficheiros = e.dataTransfer.files; if (ficheiros.length > 0) { document.getElementById('chat-file-input').files = ficheiros; dispararToastBanner("Arquivo detectado via Drop. Transmitindo...", 'info'); await enviarMensagemFormulario(); } }); } harPerfilAmigoModal(); fecharEmojiModal(); fecharMediaViewer(); isChatActive = true; atualizarBadge(); } else { isChatActive = false; } } function abrirLogin() { mudarTela('login'); } function abrirCadastro() { mudarTela('cadastro'); } // ============================================================ // LOGIN / CADASTRO // ============================================================ function entrar() { const email = document.getElementById('loginEmail').value.trim(); const senha = document.getElementById('loginSenha').value.trim(); if (!email || !senha) { showToast('Preencha todos os campos.', 'warning', 'Atenção'); return; } chamarBackend('login', { email: email, senha: senha }, function(r) { if (r.erro) { showToast(r.erro, 'error', 'Erro'); } else { usuarioAtual = r; salvarLogin(usuarioAtual); document.getElementById('usuario-nome').textContent = usuarioAtual.nome; document.getElementById('my-profile-pic').src = usuarioAtual.foto; showToast('Bem-vindo, ' + usuarioAtual.nome + '!', 'success', 'Sucesso'); mudarTela('chat'); atualizarBadge(); } }); } function cadastrar() { const nome = document.getElementById('nome').value.trim(); const idade = document.getElementById('idade').value.trim(); const email = document.getElementById('email').value.trim(); const senha = document.getElementById('senha').value.trim(); let foto = document.getElementById('foto').value.trim(); if (!nome || !idade || !email || !senha) { showToast('Preencha todos os campos obrigatórios.', 'warning', 'Atenção'); return; } if (senha.length < 6) { showToast('A senha deve ter pelo menos 6 caracteres.', 'warning', 'Atenção'); return; } if (fotoUploadBase64) { chamarBackend('uploadFotoBase64', { foto: fotoUploadBase64 }, function(r) { if (r.sucesso) { salvarUsuarioComFoto(nome, idade, email, senha, r.caminho); } else { showToast('Erro ao fazer upload da foto: ' + (r.erro || ''), 'error', 'Erro'); } }); } else { salvarUsuarioComFoto(nome, idade, email, senha, foto); } } function salvarUsuarioComFoto(nome, idade, email, senha, foto) { chamarBackend('incluirUsuario', { nome: nome, idade: idade, email: email, senha: senha, foto: foto }, function(r) { if (r.erro) { showToast(r.erro, 'error', 'Erro'); } else { showToast('Cadastro realizado com sucesso! Faça login.', 'success', 'Sucesso'); removerFotoUpload(); abrirLogin(); } }); } function logout() { showConfirm('Tem certeza que deseja sair?', function() { usuarioAtual = null; amigoAtual = null; limparLogin(); if (listaAmigosTimer) clearTimeout(listaAmigosTimer); if (mensagensTimer) clearTimeout(mensagensTimer); abrirLogin(); document.getElementById('amigo-nome').textContent = 'Selecione um Amigo'; document.getElementById('amigo-foto').src = 'https://via.placeholder.com/50/666666/ffffff?text=?'; document.getElementById('mensagens').innerHTML = '
chat
Selecione um amigo para começar
'; showToast('Você saiu com sucesso.', 'info', 'Até logo!'); atualizarBadge(); }, 'Sair', 'danger'); } // ============================================================ // PERFIL - CORRIGIDO PARA ABRIR MODAL POR CIMA // ============================================================ function abrirEdicaoPerfil() { if (!usuarioAtual) return; chamarBackend('buscarPerfil', { email: usuarioAtual.email }, function(r) { if (!r) { showToast('Erro ao buscar dados do perfil.', 'error', 'Erro'); return; } linhaAtual = r.id; document.getElementById('editNome').value = r.nome; document.getElementById('editIdade').value = r.idade; document.getElementById('editEmail').value = r.email; document.getElementById('editSenha').value = ''; document.getElementById('editFoto').value = r.foto; document.getElementById('previewFoto').src = r.foto; removerEditFotoUpload(); document.getElementById('editFoto').oninput = function(e) { document.getElementById('previewFoto').src = e.target.value || 'https://via.placeholder.com/100/1e1e1e/ffffff?text=FOTO'; }; mudarTela('perfil-edit'); }); } function salvarAlteracoesPerfil() { if (!usuarioAtual || !linhaAtual) return; const nome = document.getElementById('editNome').value.trim(); const idade = document.getElementById('editIdade').value.trim(); const senha = document.getElementById('editSenha').value.trim(); let foto = document.getElementById('editFoto').value.trim(); if (!nome || !idade) { showToast('Nome e Idade são obrigatórios!', 'warning', 'Atenção'); return; } // Usar showConfirm que agora abre por cima de tudo showConfirm('Confirma as alterações no seu perfil?', function() { if (editFotoUploadBase64) { chamarBackend('uploadFotoBase64', { foto: editFotoUploadBase64 }, function(r) { if (r.sucesso) { salvarPerfilComFoto(nome, idade, senha, r.caminho); } else { showToast('Erro ao fazer upload da foto: ' + (r.erro || ''), 'error', 'Erro'); } }); } else { salvarPerfilComFoto(nome, idade, senha, foto || usuarioAtual.foto); } }, 'Editar Perfil', 'success'); } function salvarPerfilComFoto(nome, idade, senha, foto) { chamarBackend('salvarPerfil', { id: linhaAtual, nome: nome, idade: idade, senha: senha, foto: foto }, function(r) { if (r.sucesso) { showToast('Perfil atualizado com sucesso!', 'success', 'Sucesso'); usuarioAtual.nome = nome; usuarioAtual.idade = idade; usuarioAtual.foto = r.fotoAtualizada; salvarLogin(usuarioAtual); document.getElementById('usuario-nome').textContent = nome; document.getElementById('my-profile-pic').src = r.fotoAtualizada; removerEditFotoUpload(); mudarTela('chat'); } else { showToast('Erro ao salvar perfil: ' + (r.erro || ''), 'error', 'Erro'); } }); } // ============================================================ // EMOJIS // ============================================================ function openEmojiPicker() { if (document.getElementById('campoMsg').disabled) { showToast('Selecione um amigo para enviar emojis!', 'warning', 'Atenção'); return; } const modal = document.getElementById('emoji-modal'); const list = document.getElementById('emoji-list'); list.innerHTML = ''; emojis.forEach(emoji => { const span = document.createElement('span'); span.className = 'emoji-item'; span.textContent = emoji; span.onclick = function() { selecionarEmoji(emoji); }; list.appendChild(span); }); modal.style.display = 'flex'; modal.classList.add('active'); } function fecharEmojiModal() { const modal = document.getElementById('emoji-modal'); modal.style.display = 'none'; modal.classList.remove('active'); } function selecionarEmoji(emoji) { const input = document.getElementById('campoMsg'); input.value += emoji; input.focus(); input.dispatchEvent(new Event('input')); fecharEmojiModal(); } // ============================================================ // MEDIA VIEWER // ============================================================ function abrirMediaViewer(src, tipo) { const modal = document.getElementById('media-viewer-modal'); const container = document.getElementById('media-viewer-content'); container.innerHTML = ''; if (tipo === 'imagem') { const img = document.createElement('img'); img.src = src; img.alt = 'Imagem'; container.appendChild(img); } else if (tipo === 'video') { const video = document.createElement('video'); video.src = src; video.controls = true; video.autoplay = true; video.style.maxWidth = '92vw'; video.style.maxHeight = '78vh'; container.appendChild(video); } modal.style.display = 'flex'; modal.classList.add('active'); } function fecharMediaViewer() { const modal = document.getElementById('media-viewer-modal'); const container = document.getElementById('media-viewer-content'); container.innerHTML = ''; modal.style.display = 'none'; modal.classList.remove('active'); } // ============================================================ // AMIGOS // ============================================================ function carregarAmigos() { if (!usuarioAtual) return; if (listaAmigosTimer) clearTimeout(listaAmigosTimer); chamarBackend('listarAmigos', { meuEmail: usuarioAtual.email }, function(lista) { listaAmigosCompleta = lista; renderizarListaAmigos(lista); if (amigoAtual) { const amigoData = lista.find(a => a.email === amigoAtual); if (amigoData) { amigoAtualBloqueadoPorMim = amigoData.euBloqueei; configurarInputChat(); } } listaAmigosTimer = setTimeout(carregarAmigos, 5000); }); } function renderizarListaAmigos(lista) { const div = document.getElementById('listaAmigos'); div.innerHTML = ''; if (lista.length === 0) { div.innerHTML = '
sentiment_dissatisfied
Adicione amigos!
'; } lista.sort((a, b) => { if (a.status === 'PENDENTE' && b.status !== 'PENDENTE') return -1; if (a.status !== 'PENDENTE' && b.status === 'PENDENTE') return 1; return 0; }); lista.forEach(c => { let statusParaExibir = c.status; if (c.euBloqueei) statusParaExibir = 'BLOQUEADO'; const el = document.createElement('div'); el.className = 'contato' + (amigoAtual === c.email ? ' active' : ''); el.onclick = function() { if (statusParaExibir === 'ACEITO' || statusParaExibir === 'BLOQUEADO' || statusParaExibir === 'ENVIADA') { abrirChat(c.email, c.nome, c.foto, c.euBloqueei); } else if (statusParaExibir === 'PENDENTE') { showToast('Aceite a solicitação de ' + c.nome + ' para iniciar o chat.', 'info', 'Atenção'); } }; let statusTagHTML = ''; if (statusParaExibir === 'ACEITO') { statusTagHTML = 'Amigo'; } else if (statusParaExibir === 'PENDENTE') { statusTagHTML = `
ACEITAR X
`; } else if (statusParaExibir === 'ENVIADA') { statusTagHTML = 'Pendente'; } else if (statusParaExibir === 'BLOQUEADO') { statusTagHTML = 'Bloqueado'; } const isOnline = false; const ultimaMsg = c.ultima_msg || ''; const ultimaHora = c.ultima_hora || ''; const naoLidas = c.nao_lidas || 0; const isMeuRemetente = c.ultimo_remetente === usuarioAtual.email; el.innerHTML = `
Foto de ${c.nome}
${c.nome} ${naoLidas > 0 ? `${naoLidas}` : ''}
${ultimaMsg ? (isMeuRemetente ? 'Você: ' : '') + ultimaMsg : 'Nenhuma mensagem'}
${ultimaHora ? `
${ultimaHora}
` : ''} ${statusTagHTML} `; div.appendChild(el); }); } function aceitarAmizade(emailSolicitante, nomeSolicitante, event) { event.stopPropagation(); if (!usuarioAtual) return; showConfirm('Aceitar solicitação de amizade de ' + nomeSolicitante + '?', function() { chamarBackend('aceitarSolicitacao', { meuEmail: usuarioAtual.email, emailSolicitante: emailSolicitante }, function(r) { if (r.sucesso) { showToast('Amizade com ' + nomeSolicitante + ' aceita!', 'success', 'Sucesso'); carregarAmigos(); } else { showToast('Erro ao aceitar amizade: ' + (r.erro || ''), 'error', 'Erro'); } }); }, 'Aceitar Amizade', 'success'); } function recusarAmizade(emailSolicitante, nomeSolicitante, event) { event.stopPropagation(); if (!usuarioAtual) return; showConfirm('Recusar solicitação de amizade de ' + nomeSolicitante + '?', function() { chamarBackend('recusarSolicitacao', { meuEmail: usuarioAtual.email, emailAmigo: emailSolicitante }, function(r) { if (r.sucesso) { showToast('Solicitação de ' + nomeSolicitante + ' recusada.', 'info', 'Info'); carregarAmigos(); } else { showToast('Erro ao recusar amizade: ' + (r.erro || ''), 'error', 'Erro'); } }); }, 'Recusar Amizade', 'danger'); } function adicionarAmigoUI(emailAmigo, nomeAmigo) { if (!usuarioAtual) return; const amigoExistente = listaAmigosCompleta.find(a => a.email === emailAmigo); if (amigoExistente) { showToast('Você já tem um relacionamento com ' + nomeAmigo + '.', 'warning', 'Atenção'); mudarTela('chat'); return; } showConfirm('Enviar solicitação de amizade para ' + nomeAmigo + '?', function() { chamarBackend('adicionarAmigo', { emailRemetente: usuarioAtual.email, emailDestinatario: emailAmigo }, function(r) { if (r.erro) { showToast(r.erro, 'error', 'Erro'); } else { showToast('Solicitação enviada para ' + nomeAmigo + '.', 'success', 'Sucesso'); mudarTela('chat'); } }); }, 'Adicionar Amigo', 'success'); } function filtrarAmigos() { const termo = document.getElementById('searchFriends').value.toLowerCase(); const filtrada = listaAmigosCompleta.filter(a => a.nome.toLowerCase().includes(termo) || a.email.toLowerCase().includes(termo) ); renderizarListaAmigos(filtrada); } function carregarTodosUsuarios() { if (!usuarioAtual) return; chamarBackend('listarTodosUsuarios', { emailAtual: usuarioAtual.email }, function(lista) { const div = document.getElementById('usuarios-container'); const termo = document.getElementById('searchAllUsers').value.toLowerCase(); let html = '

Usuários Disponíveis

'; const filtrados = lista.filter(c => c.nome.toLowerCase().includes(termo) || c.email.toLowerCase().includes(termo) ); if (filtrados.length === 0) { html += '
search_off
Nenhum usuário encontrado.
'; } else { filtrados.forEach(c => { html += `
${c.nome}
${c.nome}
${c.email}
person_add
`; }); } div.innerHTML = html; }); } function filtrarTodosUsuarios() { carregarTodosUsuarios(); } // ============================================================ // CHAT // ============================================================ function abrirChat(email, nome, foto, euBloqueei) { const amigoData = listaAmigosCompleta.find(a => a.email === email); if (!amigoData || (amigoData.status !== 'ACEITO' && amigoData.status !== 'BLOQUEADO' && amigoData.status !== 'ENVIADA')) { return; } if (mensagensTimer) clearTimeout(mensagensTimer); amigoAtual = email; amigoAtualNome = nome; amigoAtualFoto = foto; amigoAtualBloqueadoPorMim = euBloqueei; document.getElementById('amigo-nome').textContent = nome; document.getElementById('amigo-foto').src = foto; document.getElementById('amigo-foto').alt = 'Foto de ' + nome; renderizarListaAmigos(listaAmigosCompleta); configurarInputChat(); mensagensCache = []; atualizarMensagens(true); atualizarBadge(); chamarBackend('marcarTodasVisualizadas', { meuEmail: usuarioAtual.email, amigoEmail: amigoAtual }, function() {}); } function configurarInputChat() { const input = document.getElementById('campoMsg'); const btn = document.querySelector('#input-area .btn-send'); if (amigoAtualBloqueadoPorMim) { input.disabled = true; btn.disabled = true; input.placeholder = 'Você bloqueou este usuário'; } else { input.disabled = false; btn.disabled = false; input.placeholder = 'Digite uma mensagem...'; } } function atualizarMensagens(forcarScroll = false) { if (!amigoAtual) return; if (mensagensTimer) clearTimeout(mensagensTimer); chamarBackend('buscarMensagensEStatus', { meuEmail: usuarioAtual.email, amigoEmail: amigoAtual }, function(r) { const msgs = r.mensagens || []; const estaDigitando = r.digitando || false; const indicator = document.getElementById('typing-indicator'); indicator.style.display = estaDigitando ? 'block' : 'none'; const msgsStr = JSON.stringify(msgs); if (msgsStr === mensagensCache && !forcarScroll) { mensagensTimer = setTimeout(atualizarMensagens, 1500); return; } mensagensCache = msgsStr; const div = document.getElementById('mensagens'); const isScrolledToBottom = (div.scrollHeight - div.clientHeight) <= (div.scrollTop + 5); if (msgs.length > 0) { const lastMsg = msgs[msgs.length - 1]; if (!lastMsg.isRemetente && lastMsg.id !== lastNotifiedMsgId) { lastNotifiedMsgId = lastMsg.id; if (!isChatActive || amigoAtual !== lastMsg.remetente) { playNotificationSound(); } } } let currentDay = ''; let html = ''; msgs.forEach(function(m) { const msgDate = new Date(m.data_hora); const dayKey = msgDate.toLocaleDateString('pt-BR'); if (dayKey !== currentDay) { currentDay = dayKey; const dayLabel = msgDate.toDateString() === new Date().toDateString() ? 'Hoje' : msgDate.toDateString() === new Date(Date.now() - 86400000).toDateString() ? 'Ontem' : msgDate.toLocaleDateString('pt-BR', { weekday: 'long', day: 'numeric', month: 'long' }); html += `
${dayLabel}
`; } const isSent = m.isRemetente; const isImage = m.tipo === 'imagem'; const isVideo = m.tipo === 'video'; const mediaSrc = m.caminho || ''; const statusIcon = isSent ? (m.visualizada ? 'done_all' : 'done') : ''; let mediaHtml = ''; if (isImage) { mediaHtml = `
Imagem
`; } else if (isVideo) { mediaHtml = `
`; } const msgText = m.conteudo && !isImage && !isVideo ? m.conteudo : ''; html += `
${!isSent ? `${amigoAtualNome}` : ''}
${mediaHtml} ${msgText ? `
${msgText}
` : ''}
`; }); div.innerHTML = html; if (forcarScroll || isScrolledToBottom) { div.scrollTop = div.scrollHeight; } mensagensTimer = setTimeout(atualizarMensagens, 1500); atualizarBadge(); }); } function enviarMsg() { const input = document.getElementById('campoMsg'); const msg = input.value.trim(); if (msg === '' || !amigoAtual || amigoAtualBloqueadoPorMim) return; if (mensagensTimer) clearTimeout(mensagensTimer); chamarBackend('enviarMensagem', { emailRemetente: usuarioAtual.email, emailDestinatario: amigoAtual, mensagem: msg }, function(r) { if (r.erro) { showToast('Não foi possível enviar a mensagem: ' + r.erro, 'error', 'Erro'); } else { input.value = ''; input.dispatchEvent(new Event('input')); mensagensCache = []; atualizarMensagens(true); atualizarBadge(); } }); } function enviarArquivo(event) { const file = event.target.files[0]; if (!file || !amigoAtual || amigoAtualBloqueadoPorMim) return; if (mensagensTimer) clearTimeout(mensagensTimer); const formData = new FormData(); formData.append('acao', 'enviarMensagem'); formData.append('emailRemetente', usuarioAtual.email); formData.append('emailDestinatario', amigoAtual); formData.append('mensagem', ''); formData.append('arquivo', file); fetch('', { method: 'POST', body: formData }) .then(response => response.json()) .then(r => { if (r.erro) { showToast('Não foi possível enviar o arquivo: ' + r.erro, 'error', 'Erro'); } else { mensagensCache = []; atualizarMensagens(true); atualizarBadge(); } }) .catch(err => { showToast('Erro ao enviar arquivo.', 'error', 'Erro'); }); event.target.value = ''; } // ============================================================ // STATUS - DIGITANDO // ============================================================ function enviarStatusDigitando() { if (!amigoAtual || document.getElementById('campoMsg').disabled) return; chamarBackend('registrarStatusDigitando', { emailRemetente: usuarioAtual.email, emailAmigo: amigoAtual }, function(r) {}, false); if (typingTimeout) clearTimeout(typingTimeout); typingTimeout = setTimeout(function() {}, 2000); } // ============================================================ // PERFIL DO AMIGO // ============================================================ function abrirPerfilAmigo() { if (!amigoAtual) return; document.getElementById('modal-amigo-foto').src = amigoAtualFoto; document.getElementById('modal-amigo-nome').textContent = amigoAtualNome; document.getElementById('modal-amigo-email').textContent = amigoAtual; const btn = document.getElementById('bloquear-btn'); if (amigoAtualBloqueadoPorMim) { btn.textContent = 'Desbloquear'; btn.className = 'btn btn-success'; btn.innerHTML = 'lock_open Desbloquear'; } else { btn.textContent = 'Bloquear'; btn.className = 'btn btn-danger'; btn.innerHTML = 'block Bloquear'; } const modal = document.getElementById('perfil-amigo-modal'); modal.style.display = 'flex'; modal.classList.add('active'); } function fecharPerfilAmigoModal() { const modal = document.getElementById('perfil-amigo-modal'); modal.style.display = 'none'; modal.classList.remove('active'); } function toggleBloqueio() { const novoStatus = amigoAtualBloqueadoPorMim ? 'ACEITO' : 'BLOQUEADO'; const acao = amigoAtualBloqueadoPorMim ? 'desbloquear' : 'bloquear'; showConfirm('Tem certeza que deseja ' + acao + ' ' + amigoAtualNome + '?', function() { chamarBackend('alterarStatusBloqueio', { meuEmail: usuarioAtual.email, emailAmigo: amigoAtual, novoStatus: novoStatus }, function(r) { if (r.sucesso) { showToast('Usuário ' + r.status.toLowerCase() + ' com sucesso!', 'success', 'Sucesso'); amigoAtualBloqueadoPorMim = (r.status === 'BLOQUEADO'); fecharPerfilAmigoModal(); carregarAmigos(); configurarInputChat(); } else { showToast('Erro ao modificar status: ' + (r.erro || ''), 'error', 'Erro'); } }); }, acao.charAt(0).toUpperCase() + acao.slice(1), amigoAtualBloqueadoPorMim ? 'success' : 'danger'); } // ============================================================ // MENU DA MENSAGEM // ============================================================ function fecharMenuMensagem() { const modal = document.getElementById('message-menu-modal'); modal.style.display = 'none'; modal.classList.remove('active'); document.getElementById('edit-area').style.display = 'none'; document.getElementById('menu-options').style.display = 'block'; mensagemSelecionadaId = null; } function showMenuOptions() { document.getElementById('edit-area').style.display = 'none'; document.getElementById('menu-options').style.display = 'block'; } function abrirMenuMensagem(msgId, msgTexto) { mensagemSelecionadaId = msgId; document.getElementById('message-content-preview').textContent = msgTexto; const modal = document.getElementById('message-menu-modal'); modal.style.display = 'flex'; modal.classList.add('active'); } function confirmarExclusaoMensagem() { if (!mensagemSelecionadaId) return; showConfirm('ATENÇÃO: Deseja realmente EXCLUIR esta mensagem?', function() { chamarBackend('excluirMensagem', { mensagemId: mensagemSelecionadaId }, function(r) { if (r.sucesso) { showToast('Mensagem excluída com sucesso!', 'success', 'Sucesso'); fecharMenuMensagem(); mensagensCache = []; if (mensagensTimer) clearTimeout(mensagensTimer); atualizarMensagens(true); } else { showToast('Erro ao excluir mensagem: ' + (r.erro || ''), 'error', 'Erro'); } }); }, 'Excluir Mensagem', 'danger'); } function abrirEdicaoMensagem() { const previewText = document.getElementById('message-content-preview').textContent; document.getElementById('editMessageInput').value = previewText; document.getElementById('edit-area').style.display = 'block'; document.getElementById('menu-options').style.display = 'none'; document.getElementById('editMessageInput').focus(); } function salvarEdicaoMensagem() { if (!mensagemSelecionadaId) return; const novoTexto = document.getElementById('editMessageInput').value.trim(); if (novoTexto === '') { showToast('A mensagem editada não pode estar vazia.', 'warning', 'Atenção'); return; } showConfirm('Confirma a edição desta mensagem?', function() { chamarBackend('editarMensagem', { mensagemId: mensagemSelecionadaId, novoTexto: novoTexto }, function(r) { if (r.sucesso) { showToast('Mensagem editada com sucesso!', 'success', 'Sucesso'); fecharMenuMensagem(); mensagensCache = []; if (mensagensTimer) clearTimeout(mensagensTimer); atualizarMensagens(true); } else { showToast('Erro ao editar mensagem: ' + (r.erro || ''), 'error', 'Erro'); } }); }, 'Editar Mensagem', 'success'); } // ============================================================ // BADGE // ============================================================ function atualizarBadge() { if (!usuarioAtual) return; chamarBackend('buscarNaoLidasTotal', { meuEmail: usuarioAtual.email }, function(r) { unreadCount = r.total || 0; document.title = unreadCount > 0 ? '(' + unreadCount + ') GGMSG' : 'GGMSG'; }, false); } // ============================================================ // RIPPLE // ============================================================ document.addEventListener('click', function(e) { const btn = e.target.closest('.btn'); if (btn) { const ripple = document.createElement('span'); ripple.className = 'ripple'; const rect = btn.getBoundingClientRect(); ripple.style.left = (e.clientX - rect.left) + 'px'; ripple.style.top = (e.clientY - rect.top) + 'px'; ripple.style.width = ripple.style.height = '20px'; btn.appendChild(ripple); setTimeout(() => ripple.remove(), 600); } }); // ============================================================ // INICIALIZAÇÃO // ============================================================ document.addEventListener('DOMContentLoaded', function() { const textarea = document.getElementById('campoMsg'); if (textarea) { textarea.addEventListener('input', function() { this.style.height = 'auto'; this.style.height = Math.min(this.scrollHeight, 100) + 'px'; }); textarea.addEventListener('keydown', function(e) { if (e.key === 'Enter' && !e.shiftKey && !this.disabled) { e.preventDefault(); enviarMsg(); } }); textarea.addEventListener('keyup', function() { enviarStatusDigitando(); }); } ['fotoUploadArea', 'editFotoUploadArea'].forEach(id => { const area = document.getElementById(id); if (area) { area.addEventListener('dragover', function(e) { e.preventDefault(); this.classList.add('dragover'); }); area.addEventListener('dragleave', function(e) { e.preventDefault(); this.classList.remove('dragover'); }); area.addEventListener('drop', function(e) { e.preventDefault(); this.classList.remove('dragover'); const files = e.dataTransfer.files; if (files.length > 0) { const input = this.querySelector('input[type="file"]'); if (input) { input.files = files; input.dispatchEvent(new Event('change')); } } }); } }); document.querySelectorAll('.modal-overlay').forEach(modal => { modal.addEventListener('click', function(e) { if (e.target === this) { this.style.display = 'none'; this.classList.remove('active'); if (this.id === 'confirm-modal') confirmCallback = null; } }); }); if (!carregarLogin()) { abrirLogin(); } else { atualizarBadge(); } });